package com.cea.papyrus.diagram.sequence.helper;

import org.eclipse.uml2.uml.ActionExecutionSpecification;
import org.eclipse.uml2.uml.BehaviorExecutionSpecification;
import org.eclipse.uml2.uml.CombinedFragment;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.DurationObservation;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.InteractionUse;
import org.eclipse.uml2.uml.Lifeline;
import org.eclipse.uml2.uml.OccurrenceSpecification;
import org.eclipse.uml2.uml.StateInvariant;
import org.eclipse.uml2.uml.TimeObservation;

import com.cea.papyrus.core.IPapyrusUIConstants;
import com.cea.papyrus.core.helper.DefaultModelerHelper;
import com.cea.papyrus.core.helper.IGraphElementHelper;
import com.cea.papyrus.diagram.classdiagram.helper.EdgeGraphLinkHelper;
import com.cea.papyrus.diagram.classdiagram.helper.NodeCommentHelper;
import com.cea.papyrus.diagram.classdiagram.helper.NodeConstraintHelper;

/**
 * Model factory for sequence diagrams.
 * 
 * @author Frank Davidsen
 */
public class SequenceDiagramModelerHelper extends DefaultModelerHelper {

    /** Singleton instance of this class. Lazily instantiated. */
    private static SequenceDiagramModelerHelper INSTANCE;

    // List of UML elements that can be created.
    @SuppressWarnings("unchecked")
    protected final Class elementTypes[] = {
        // nodes
		Comment.class,
		Constraint.class,
        Interaction.class,
        Lifeline.class,
        BehaviorExecutionSpecification.class,
        ActionExecutionSpecification.class,
        StateInvariant.class,
        OccurrenceSpecification.class,
        InteractionUse.class,
        CombinedFragment.class,
        TimeObservation.class,
        DurationObservation.class,
        // templates
        // edges
		com.cea.papyrus.core.pseudoelement.GraphicalLink.class,
		com.cea.papyrus.diagram.sequence.pseudoelement.DurationObservationLink.class,
		com.cea.papyrus.diagram.sequence.pseudoelement.TimeObservationLink.class,
    };

    // Set of factory that are in the same order that element types
    protected final IGraphElementHelper nodeFactory[] = {
        // nodes
    		new NodeCommentHelper(),
    		new NodeConstraintHelper(),
            new NodeInteractionHelper(),
            new NodeLifelineHelper(),
            new NodeExecutionSpecificationHelper(),
            new NodeExecutionSpecificationHelper(),
            new NodeStateInvariantHelper(),
            new NodeOccurenceSpecificationHelper(),
            new NodeInteractionUseHelper(),
            new NodeCombinedFragmentHelper(),
            new NodeTimeObservationHelper(),
            new NodeDurationObservationHelper(),
        // templates
        // edges
            new EdgeGraphLinkHelper(),
            new EdgeDurationObservationHelper(),
            new EdgeTimeObservationHelper(),
        };

    /**
     * Private constructor. Use {@link #getInstance()} to get an instance of this class.
     */
    public SequenceDiagramModelerHelper() {
        for (int i = 0; i < this.elementTypes.length; i++) {
            this.creationFactoryMap.put(this.elementTypes[i], this.nodeFactory[i]);
        }
    }

    /**
     * Returns the unique instance of this class.
     * 
     * @return an instance of this class.
     */
    public static SequenceDiagramModelerHelper getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new SequenceDiagramModelerHelper();
        }
        return INSTANCE;
    }

    @Override
    public String getId() {
        return IPapyrusUIConstants.SEQUENCE_DIAGRAM;
    }
}
